home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 8
/
Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso
/
Aminet
/
text
/
hyper
/
wrapag.lha
/
WrapAG
/
wrapag.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-18
|
10KB
|
528 lines
/* wrapag.c v1 By Bill the Hamster, godfrey2@coventry.ac.uk *
* Copyright, Bill Godfrey, UK, 1995. See file COPYING for Licence.
* Written for DICE C on the Amiga 1200.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define DEFAULTLINEWIDTH 75
int linewidth; /* Line width, set by parameters in function main. */
struct linenode { /* A line of text. */
char text[255]; /* The line. */
struct linenode *next; /* List link. */
};
struct paragraph { /* A paragraph of text, made up of lines. */
struct linenode *head; /* Head of list of lines. */
struct linenode *last; /* Last item in list. */
};
void newparagraph(struct paragraph *p) /* Init new paragraph. */
{
p->head=NULL;
p->last=NULL;
}
void emptyparagraph(struct paragraph *p) /* Clear old paragraph. */
{
struct linenode *curr;
struct linenode *link;
curr=p->head;
while (curr != NULL) {
link=curr->next;
free(curr);
curr=link;
}
newparagraph(p);
}
int addlinetop(struct paragraph *p, char *s) /* Add line to paragraph. */
{
struct linenode *nl;
nl=malloc(sizeof(struct linenode));
if (nl == NULL) { /* Not enough memory? */
return(FALSE);
}
else {
strcpy(nl->text,s);
nl->next=NULL; /* Setup new node. */
if (p->head == NULL) {
p->head=nl;
p->last=nl; /* Start empty list. */
}
else {
p->last->next=nl;
p->last=nl; /* Continue existing list. */
}
return(TRUE);
}
}
void getline(FILE *inf, char *s, int maxline) /* Get a line of text from a file. */
{
char inc; /* Charcter to be inputted. */
int charin; /* Length of s. */
s[0]='\0';
charin=0;
inc=fgetc(inf);
while ((!feof(inf)) && (inc != '\n') && (charin<maxline)) {
s[charin]=inc;
charin++;
inc=fgetc(inf);
}
s[charin]='\0';
}
struct wordnode { /* A word. */
char word[255]; /* The word. */
int alen; /* Actual length of word. */
int vlen; /* Virtual length. */
int ns; /* No. of spaces. */
struct wordnode *next; /* List link. */
};
/* Paragraphs which begin with a space will have the first
word as a space or tab only, with alen, vlen and ns all equal. */
struct wordlist {
struct wordnode *head; /* Head of the word list. */
};
void newwordlist(struct wordlist *wl) /* Start a new word list. */
{
wl->head=NULL;
}
void emptywordlist(struct wordlist *wl) /* Empty a word list. */
{
struct wordnode *curr;
struct wordnode *link;
curr=wl->head;
while (curr != NULL) {
link=curr->next;
free(curr);
curr=link;
}
newwordlist(wl);
}
void remtrail(char *s) /* Remove all trailing whitespace. */
{
int lastchar;
int c;
lastchar=0;
c=0;
while (s[c] != '\0') {
if ((s[c] != ' ') && (s[c] != '\t') && (s[c] != '\n') && (s[c] != '\0')) {
lastchar=c;
}
c++;
}
s[lastchar+1]='\0';
}
void addaspace(char *s)
{
int sl;
sl=strlen(s);
s[sl]=' ';
s[sl+1]='\0';
}
char nextchar(struct linenode *curr, int cinl) /* Look ahead to see what the next char is. */
{
char nc;
nc=curr->text[cinl];
if (nc == '\0') {
if (curr->next != NULL) {
nc=curr->next->text[0];
}
}
return(nc);
}
char loadchar(struct linenode **curr, int *cinl)
{
char res;
res=nextchar(*curr,*cinl);
if (res == '\0') {
(*curr)=NULL;
cinl=0;
}
else {
(*cinl)++;
if ((*curr)->text[*cinl] == '\0') {
if ((*curr)->next != NULL) {
*curr=(*curr)->next;
*cinl=0;
}
}
}
return(res);
}
void setns(struct wordnode *w)
{
int c;
int res;
c=w->alen-1;
res=0;
while (((w->word[c] == ' ') || (w->word[c] == '\t')) && (c != 0)) {
c--;
res++;
}
if (c == 0) { /* If we fall out of the loop, c==0, add one to res. */
res++;
}
w->ns=res;
}
void splittowords(struct paragraph *p, struct wordlist *wl)
{
struct wordnode *tempw;
struct wordnode *currw;
struct wordnode *prevw; /* List points for wordlist. */
struct linenode *currl; /* Current line. */
int cinl; /* Character in line. */
char inc; /* Character input. */
int inalink; /* Are we inside a link button text? */
newwordlist(wl);
prevw=NULL;
currw=malloc(sizeof(struct wordnode));
wl->head=currw;
currw->word[0]='\0';
currw->alen=0;
currw->vlen=0;
currw->ns=0;
currw->next=NULL;
currl=p->head;
cinl=0;
inalink=FALSE;
inc=loadchar(&currl,&cinl);
while (inc != '\0') {
if ((inalink == TRUE) && (inc == '\"')) {
while (inc != '}') {
currw->word[currw->alen]=inc;
currw->alen++;
inc=loadchar(&currl,&cinl);
}
currw->word[currw->alen]=inc;
currw->alen++;
currw->word[currw->alen]='\0';
inalink=FALSE;
}
else if (inc == '\\') {
currw->word[currw->alen]=inc;
currw->alen++;
currw->word[currw->alen]=loadchar(&currl,&cinl);
currw->alen++;
currw->word[currw->alen]='\0';
currw->vlen++;
}
else if ((inc == '@') && (nextchar(currl,cinl) == '{')) {
inc=loadchar(&currl,&cinl); /* And ignore it. */
inc=loadchar(&currl,&cinl);
if (inc == '\"') {
inalink=TRUE;
currw->word[currw->alen]='@';
currw->alen++;
currw->word[currw->alen]='{';
currw->alen++;
currw->word[currw->alen]='\"';
currw->alen++;
currw->word[currw->alen]='\0';
}
else {
currw->word[currw->alen]='@';
currw->alen++;
currw->word[currw->alen]='{';
currw->alen++;
while (inc != '}') {
currw->word[currw->alen]=inc;
currw->alen++;
inc=loadchar(&currl,&cinl);
}
currw->word[currw->alen]='}';
currw->alen++;
currw->word[currw->alen]='\0';
}
}
else if (((inc == ' ') || (inc == '\t')) && ((nextchar(currl,cinl) != ' ') && (nextchar(currl,cinl) != '\t'))) {
currw->word[currw->alen]=inc;
currw->alen++;
currw->word[currw->alen]='\0';
currw->vlen++;
setns(currw);
if (wl->head == NULL) { /* Empty list? */
wl->head=currw;
}
else {
prevw->next=currw;
prevw=currw;
tempw=malloc(sizeof(struct wordnode));
tempw->word[0]='\0';
tempw->alen=0;
tempw->vlen=0;
tempw->ns=0;
tempw->next=NULL;
currw->next=tempw;
currw=tempw;
}
}
else {
currw->word[currw->alen]=inc;
currw->alen++;
currw->word[currw->alen]='\0';
currw->vlen++;
}
inc=loadchar(&currl,&cinl);
}
if (currw->alen != 0) {
setns(currw);
if (wl->head == NULL) {
wl->head=currw;
}
else {
prevw->next=currw;
prevw=currw;
}
}
}
void testwraptext(struct wordlist *wl, int width, FILE *outf)
{
struct wordnode *curr;
printf("-=-=-=-=- New wordlist. -=-=-=-=-\n");
curr=wl->head;
while (curr != NULL) {
printf(">%s< %d %d %d\n",curr->word, curr->alen, curr->vlen, curr->ns);
curr=curr->next;
}
printf("-=-=-=-=-=- End of wordlist. -=-=-=-=-=-\n");
}
void wraptext(struct wordlist *wl, int width, FILE *outf)
{
struct wordnode *curr;
char work[255]; /* For modifying words. */
char line[255]; /* The current line. */
int alength; /* Actual length of line. */
int vlength; /* Virtual length of line. */
alength=0;
vlength=0;
curr=wl->head;
line[0]='\0';
while (curr != NULL) {
if (vlength + curr->vlen - curr->ns > width) {
remtrail(line);
fprintf(outf,"%s\n",line);
strcpy(line,curr->word);
alength=curr->alen;
vlength=curr->vlen;
}
else {
strcat(line,curr->word);
alength+=curr->alen;
vlength+=curr->vlen;
}
curr=curr->next;
}
fprintf(outf,"%s\n",line);
}
/* Cut bit out of wrap text, inside loop.
if (curr->vlen+charc <= width) {
fprintf(outf,"%s",curr->word);
charc += curr->vlen;
}
else if ((curr->vlen - curr->ns) + charc <= width ) {
strcpy(work,curr->word);
remtrail(work);
fprintf(outf,"%s",work);
}
else {
fprintf(outf,"\n%s",curr->word);
charc=curr->vlen;
}
curr=curr->next;
*/
void testprocp(struct paragraph *p)
{
struct linenode *curr;
curr=p->head;
while (curr != NULL) {
printf(">%s<\n",curr->text);
curr=curr->next;
}
}
void procp(struct paragraph *p, FILE *outf) /* Process paragraph and output. */
{
struct linenode *curr;
struct wordlist words;
if (p->head != NULL) {
curr=p->head;
while (curr != NULL) {
remtrail(curr->text);
if (curr->next != NULL) {
addaspace(curr->text);
}
curr=curr->next;
}
splittowords(p,&words);
wraptext(&words,linewidth,outf);
emptywordlist(&words);
}
/*testprocp(p);*/
}
void dowrap(FILE *inf, FILE *outf)
{
char s[255];
struct paragraph pgraph;
newparagraph(&pgraph);
getline(inf,s,254);
while (! feof(inf)) {
if ((s[0] == '@') && (s[1] != '{')) { /* Directive? */
procp(&pgraph,outf);
emptyparagraph(&pgraph);
fprintf(outf,"%s\n",s);
}
else if (s[0] == '\0') { /* Blank line. */
procp(&pgraph,outf);
emptyparagraph(&pgraph);
fprintf(outf,"\n",s);
}
else if ((s[0] == ' ') || (s[0] == '\t')) { /* Space/Tab */
procp(&pgraph,outf);
emptyparagraph(&pgraph);
addlinetop(&pgraph, s);
}
else { /* Normal line. */
addlinetop(&pgraph, s);
}
getline(inf,s,254);
}
procp(&pgraph,outf);
}
void syntax()
{
printf("WrapAG. By Bill the Hamster.\n");
printf(" © Bill Godfrey, UK, 1995.\n\n");
printf("Syntax;\n");
printf(" WrapAG [-Wn] file.guide\n Outputs wrapped file to screen.\n");
printf(" WrapAG [-Wn] file.guide outfile.guide\n Outputs wrapped file to outfile.guide\n\n");
printf("\nInsert -W<number> for a specific line width, EG -W50. 74 by default.\n\n");
printf("Licensed under the GNU General Public License, Version 2.\nPlease refer to file 'COPYING' for copyright notice.\n");
}
main(int argc, char **argv)
{
FILE *infile;
FILE *outfile;
int p1;
if ((argc == 1) || (argc >= 5)) {
syntax();
}
else {
linewidth=74; /* Set the default width. */
if ((argv[1][0] == '-') && ((argv[1][1] == 'W') || (argv[1][1] == 'w'))) {
if ((argv[1][2] < '0') || (argv[1][2] > '9')) {
printf("Failed maths, did we?\n N U M B E R !\n");
syntax();
exit(28);
}
linewidth=atoi(&argv[1][2]);
if ((linewidth < 1) || (linewidth >250)) {
printf("A bit out of range, perhaps. Min=1, Max=250\n");
syntax();
exit(42);
}
p1=2;
}
else {
p1=1;
}
infile=fopen(argv[p1],"r");
if (infile == NULL) {
printf("Error. Cannout open file, '%s'.\n",argv[1]);
}
else {
if (argc == 1+p1) {
dowrap(infile,stdout);
}
else {
outfile=fopen(argv[p1+1],"w");
if (outfile == NULL) {
printf("Error. Cannot open file. '%s'.\n",argv[2]);
}
else {
dowrap(infile,outfile);
fclose(outfile);
}
}
fclose(infile);
}
}
}